import { 
  AmbientLight,
  Color,
  Geometry,
  PerspectiveCamera, 
  Points, 
  PointsMaterial, 
  Scene, 
  SpotLight, 
  Vector3, 
  WebGLRenderer
} from "three"
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'
import stats from "../../utils/stats"
import { GUI } from 'dat.gui'

const scene = new Scene()
const camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000)
camera.position.set(-20, 12, 200)
camera.lookAt(0, 0, 0)

const renderer = new WebGLRenderer({ antialias: true })
renderer.setClearColor(0x000000)
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

const ambient = new AmbientLight(0x0c0c0c)
scene.add(ambient)

const spotlight = new SpotLight(0xffffff)
spotlight.position.set(100, 100, 100)
scene.add(spotlight)
// scene.add(new SpotLightHelper(spotlight))

let points: Points
const controls = {
  animate: true,
  size: 4,
  color: 0xffffff,
  transparents: true,
  opacity: 0.6,

  draw() {
    createParticles(this.size, this.transparents, this.opacity, true, true, this.color, 0x00ff00)
  }
}

controls.draw()

const gui = new GUI();
gui.add(controls, 'animate').name('启用动画')
gui.add(controls, 'transparents').name('透明化').onChange(controls.draw.bind(controls))
gui.add(controls, 'opacity', 0, 1).name('透明度').onChange(controls.draw.bind(controls))
gui.addColor(controls, 'color').name('颜色')
gui.add(controls, 'size', 1, 10, 1).name('大小').onChange(controls.draw.bind(controls))

const trackballControls = new TrackballControls(camera, renderer.domElement)

function render() {
  stats.update()
  trackballControls.update()

  if (controls.animate) {
    points.rotation.y += 0.01
    points.rotation.x += 0.01
  }

  requestAnimationFrame(render)
  renderer.render(scene, camera)
}
render()

/** 创建粒子 */
function createParticles(
  size: number, 
  transparent: boolean, 
  opacity: number, 
  vertexColors: boolean, 
  sizeAttenuation: boolean, 
  color: number, 
  vertexColor: number
) {

  if (points) scene.remove(points)

  let geom = new Geometry()
  let material = new PointsMaterial({
    size,
    transparent,
    opacity,
    vertexColors,
    sizeAttenuation,
    color: new Color(color)
  })

  let range = 500
  for (let i = 0; i < 15000; i++) {
    let x = Math.random() * range - range / 2
    let y = Math.random() * range - range / 2
    let z = Math.random() * range - range / 2
    let particle = new Vector3(x, y, z)
    geom.vertices.push(particle)

    let color = new Color(vertexColor)
    let asHSL = {h:0, s: 0, l:0}
    color.getHSL(asHSL)
    color.setHSL(asHSL.h, asHSL.s, Math.random() * asHSL.l)
    geom.colors.push(color)
  }

  points = new Points(geom, material)
  scene.add(points)
}